/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"io"
	"os"
	"strings"

	"gitee.com/bjf-fhe/apicat/entry"
	"gitee.com/bjf-fhe/apicat/notify"
	"gitee.com/bjf-fhe/apicat/platform"
	"gitee.com/bjf-fhe/apicat/source"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var notifyConfig notify.Config

// watchCmd represents the watch command
var watchCmd = &cobra.Command{
	Use:   "watch",
	Short: "实时监听日志，推送错误警报",
	Long:  `对日志的实时生成条目进行即时增量读取，对其中的错误情况按配置汇报给下游，实现安全联动`,
	Run: func(cmd *cobra.Command, args []string) {

		dest, _ := cmd.Flags().GetString("dest")

		notifier, err := platform.GetNotifier(dest, &notifyConfig)

		var notifiChan chan *entry.LogEntry
		if err == nil {
			notifiChan, err = notify.GetChannel(dest, notifier, &notifyConfig)
		}

		if err != nil {
			cmd.PrintErr(err)
			os.Exit(1)
		}

		api, baseUrl, err := rootConfig.LoadApi()
		if err == nil {

			if len(args) > 0 {

				rootConfig.file = args[0]

				if err != nil {
					cmd.PrintErr("打开日志文件出错", err)
					os.Exit(1)
				}

				var reader source.Reader
				reader, err = platform.GetSource(rootConfig.SourceMode, &rootConfig, true)
				if err != nil {
					cmd.PrintErr(err)
					os.Exit(1)
				}

				// if rootConfig.CsvMode {
				// 	parser, err = csv.NewParser()
				// } else {
				// 	// Read from STDIN and use log_format to parse log records
				// 	parser, err = nginx.NewParser(nginxConfig, rootConfig.Format, rootConfig.TimeFormat)
				// }

				if err != nil {
					cmd.PrintErrln(err)
					os.Exit(1)
				}

				//t.Lines is a channel
				for recAndError := range reader.Records() {
					// rec, err := reader.Read()
					rec := recAndError.Entry
					err := recAndError.Error
					if err == io.EOF {
						logrus.Info("读取EOF")
						continue
					} else if err != nil {
						cmd.PrintErr("读取日志内容出错", err)
						os.Exit(1)
					}
					rec.SeperatePath()
					var relatedPath = strings.TrimPrefix(rec.Url, baseUrl)

					if path, ok := api.Paths[relatedPath]; ok {
						method := path.GetOperation(rec.Method)
						if method != nil {
							rec.Legal = true
							rec.ErrorType = entry.Legal //TODO 细分
							rec.DetectErrorByDef(method)
						} else {
							rec.ErrorType = entry.Illegal_Method
						}
					} else if rootConfig.IsStaticPath(relatedPath) {
						rec.ErrorType = entry.Illegal_StaticView
					} else {
						rec.ErrorType = entry.Illegal_UnknownUrl
					}
					//else rec.Legal = false
					notifiChan <- rec
				}

			} else {
				cmd.PrintErr("没有指定日志文件路径")
				os.Exit(1)
			}
		} else {
			cmd.PrintErr(err)
			os.Exit(1)
		}
	},
}

func init() {
	rootCmd.AddCommand(watchCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// watchCmd.PersistentFlags().String("foo", "", "A help for foo")

	platform.AddFlags(watchCmd.Flags())

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	watchCmd.Flags().IntVar(&notifyConfig.MinLevel, "level", int(entry.Illegal_UnknownUrl), "最低的错误级别")
	watchCmd.Flags().IntVar(&notifyConfig.MinCount, "count", 2, "最低的错误次数")
	watchCmd.Flags().String("dest", "nginx", "输出模式，nginx:输出为nginx配置,aliyun:输出为aliyun配置模式，echo:屏幕打印模式")
}
